#include <iostream>

using std::cout;
using std::endl;

//指针与引用的区别？
//int *p;
//int &ref;

void test()
{
    int number = 10;
    //引用是一个变量的别名，操作引用与操作变量本身是一样的
    //C++中引入引用的目的，就是为了减少指针的使用
    int &ref = number;

    cout << "number = " << number << endl;
    cout << "ref = " << ref << endl;
    printf("&number = %p\n", &number);
    printf("&ref = %p\n", &ref);

    cout << endl;
    ref = 20;
    cout << "number = " << number << endl;
    cout << "ref = " << ref << endl;

    cout << endl;
    number = 30;
    cout << "number = " << number << endl;
    cout << "ref = " << ref << endl;

    cout << endl;
    int number2 = 1234;
    ref = number2;
    cout << "number = " << number << endl;
    cout << "number2 = " << number2 << endl;
    cout << "ref = " << ref << endl;
    printf("&number = %p\n", &number);
    printf("&number2 = %p\n", &number2);
    printf("&ref = %p\n", &ref);

    cout << endl;
    //引用底层实现就是一个指针(* const),指针常量
    //引用在定义的时候，必须要进行初始化，不能单独存在
    //引用一经绑定，就不能改变指向
    /* int &ref1;//error */
}

//1、引用作为函数的参数？
#if 0
//值传递====副本
//如果将int换成其他的类型的话（struct），就会有拷贝开销
void swap(int x, int y)//int x = a, int y = b
{
    int tmp = x;
    x = y;
    y = tmp;
}
#endif

#if 0
//值传递====地址
//直观性不好
void swap(int *px, int *py)//int *px = &a, int *py = &b
{
    int tmp = *px;
    *px = *py;
    *py = tmp;
}
#endif

//操作引用与操作变量本身是一样的效果，直观性好一些。
void swap(int &x, int &y)//int &x = a, int &y = b
{
    int tmp = x;
    x = y;
    y = tmp;
}

void test2()
{
    int a = 3, b = 4;
    cout << "交换之前a = " << a << ", b = " << b << endl;
    swap(a, b);
    cout << "交换之后a = " << a << ", b = " << b << endl;
}

//2、引用可以作为函数的返回类型？
int func()
{
    int number = 10;
    return number;//在执行return时候，会有拷贝操作
}

//不要返回局部变量的引用，因为其生命周期已经结束了
int &func2()
{
    int number = 10;
    return number;//在执行return时候，会有拷贝操作
}

//返回引用的前提：实体的生命周期一定要大于函数的生命周期
int arr[10] = {1, 2, 3, 5, 7, 9};
int &getIndex(size_t idx)
{
    return arr[idx];//函数的返回类型如果是引用的话，减少拷贝操作
}

void test3()
{
    cout << "getIndex(0) = " << getIndex(0) << endl;
    /* arr[0] = 100;//ok */
    getIndex(0) = 100;
    cout << "getIndex(0) = " << getIndex(0) << endl;
    cout << "arr[0] = " << arr[0] << endl;

#if 0
    &getIndex(0);//ok
    &func();//error

    func() = 20;//error
#endif
}

//如果使用堆空间的话，如果可以进行自动内存回收的话，这种写法
//也是可以的
int &getHeapData()
{
    int *pInt = new int(10);

    return *pInt;
}

void test4()
{
    int a = 3, b = 4;
    int c = a + getHeapData() + b;//内存泄漏（new的操作中没有delete）
    cout << "c = " << c << endl;

    int &ref = getHeapData();
    cout << "ref = " << ref << endl;

    delete &ref;
}

int main(int argc, char **argv)
{
    test4();
    return 0;
}

